package com.nineclock.system.service.impl;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import java.util.Date;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.common.constant.NcConstant;
import com.nineclock.common.constant.SMSConstant;
import com.nineclock.common.entity.Result;
import com.nineclock.common.enums.MessageTypeEnum;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.filter.CurrentUserHolder;
import com.nineclock.common.oss.OssClientUtils;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.system.dto.SysApplyJoinCompanyUserDTO;
import com.nineclock.system.dto.SysCompanyDTO;
import com.nineclock.system.dto.SysCompanyUserDTO;
import com.nineclock.system.dto.SysUserDTO;
import com.nineclock.system.mapper.*;
import com.nineclock.system.msg.MessageDTO;
import com.nineclock.system.pojo.*;
import com.nineclock.system.service.SysCompanyService;
import com.nineclock.system.service.SysUserService;
import io.swagger.annotations.ApiOperation;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

@Service
@Transactional
public class SysCompanyServiceImpl implements SysCompanyService {

    @Autowired
    private SysCompanyMapper companyMapper;

    @Autowired
    private OssClientUtils ossClientUtils;

    @Autowired
    private SysCompanayUserMapper companyUserMapper;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private SysRoleMapper roleMapper;

    @Autowired
    private SysCompanyUserRoleMapper companyUserRoleMapper;

    @Autowired
    private SysUserService userService;

    @Autowired
    private SysUserMapper userMapper;

    @Autowired(required = false)
    private RocketMQTemplate rocketMQTemplate;

    /**
     * 根据用户ID获取关联的企业列表
     *
     * @param userId
     * @return
     */
    @Override
    public List<SysCompanyDTO> queryUserJoinCompany(Long userId) {
        if (userId == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        List<SysCompany> companyList = companyMapper.queryUserJoinCompany(userId);
        if (CollectionUtils.isEmpty(companyList)) {
            throw new NcException(ResponseEnum.USER_NOT_JOIN_COMPANY);
        }
        List<SysCompanyDTO> companyDTOList = BeanHelper.copyWithCollection(companyList, SysCompanyDTO.class);
        return companyDTOList;
    }

    /**
     * 企业管理: 查询当前企业信息
     * 接口路径：GET/sys/company
     */
    @Override
    public SysCompanyDTO queryCompanyInfo() {
        // 获取当前登录用户id
        Long companyId = CurrentUserHolder.get().getCompanyId();
        // 根据id查询企业信息
        SysCompany company = companyMapper.selectById(companyId);
        if (company == null) {
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }
        return BeanHelper.copyProperties(company, SysCompanyDTO.class);
    }


    //上传企业Logo
    @Override
    public String uploadCompanyLogo(MultipartFile file) throws Exception {
        if (file == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        if (!NcConstant.ALLOWED_IMG_TYPES.contains(file.getContentType())) {
            throw new NcException(ResponseEnum.INVALID_FILE_TYPE);
        }
        if (file.getSize() > NcConstant.maxFileSize) {
            throw new NcException(ResponseEnum.FILE_SIZE_EXCEED_MAX_LIMIT);
        }
        String urlStr = ossClientUtils.uploadFile(file.getOriginalFilename(), file.getInputStream());
        return urlStr;
    }

    /**
     * 更新企业基本信息
     *
     * @param sysCompanyDTO
     */
    @Override
    public void updateCompanyInfo(SysCompanyDTO sysCompanyDTO) {
        // 参数校验
        if (sysCompanyDTO == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        // 获取当前登录用户所属企业id
        Long companyId = CurrentUserHolder.get().getCompanyId();

        // 更新企业信息
        SysCompany sysCompany = new SysCompany();
        sysCompany.setName(sysCompanyDTO.getName());
        sysCompany.setLogo(sysCompanyDTO.getLogo());
        sysCompany.setId(companyId);
        companyMapper.updateById(sysCompany);
        // 更新企业员工中的企业名称
        SysCompanyUser sysCompanyUser = new SysCompanyUser();
        sysCompanyUser.setCompanyName(sysCompanyDTO.getName());
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysCompanyUser::getCompanyId, companyId);
        companyUserMapper.update(sysCompanyUser, wrapper);
    }

    /**
     * 企业管理: 获取企业当前主管理员
     *
     * @return
     */
    @Override
    public SysCompanyUserDTO queryCurrentAdmin() {
        Long companyId = CurrentUserHolder.get().getCompanyId();
        SysCompanyUser sysCompanyUserAdmin = companyUserMapper.queryMainAdminCompanyUser(companyId);
        if (sysCompanyUserAdmin == null) {
            throw new NcException(ResponseEnum.COMPANY_ADMIN_NOT_EXISTS);
        }
        return BeanHelper.copyProperties(sysCompanyUserAdmin, SysCompanyUserDTO.class);
    }


    //接口名称：企业管理: 更改系统管理员
    @Override
    public void changeSysAdmin(String code, Long userId) {
        if (StringUtils.isEmpty(code) || userId == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        SysCompanyUser companyUser = companyUserMapper.selectById(userId);

        String redisCode = (String) redisTemplate.opsForValue().get(SMSConstant.SMS_CHANGE_MANAGER_KEY_PREFIX + companyUser.getMobile());
        if (StringUtils.isEmpty(code) || !redisCode.equals(code)) {
            throw new NcException(ResponseEnum.INVALID_VERIFY_CODE);
        }
        // 先查询原本的主管理员id
        SysCompanyUserDTO currentAdmin=this.queryCurrentAdmin();
        // 查询系统管理员的角色id
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRole::getCompanyId,currentAdmin.getCompanyId());
        wrapper.eq(SysRole::getRoleName,NcConstant.ADMIN_ROLE_SYS);
        SysRole sysRole = roleMapper.selectOne(wrapper);


        // 更换管理员
        LambdaQueryWrapper<SysCompanyUserRole> updateWrapper = new LambdaQueryWrapper<>();
        updateWrapper.eq(SysCompanyUserRole::getCompanyId,companyUser.getCompanyId());
        updateWrapper.eq(SysCompanyUserRole::getRoleId,sysRole.getId());
        SysCompanyUserRole sysCompanyUserRole=new SysCompanyUserRole();
        sysCompanyUserRole.setCompanyUserId(userId);
        companyUserRoleMapper.update(sysCompanyUserRole,updateWrapper);

    }

    @Override
    public List<SysCompanyDTO> queryCompanyByName(String keyword) {
        if (keyword==null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        LambdaQueryWrapper<SysCompany> wrapper =new LambdaQueryWrapper<>();
        wrapper.like(SysCompany::getName,keyword);
        List<SysCompany> companyList = companyMapper.selectList(wrapper);
        List<SysCompanyDTO> companyDTOList = BeanHelper.copyWithCollection(companyList, SysCompanyDTO.class);
        return companyDTOList;
    }

    @Override
    public void applyJoinCompany(SysApplyJoinCompanyUserDTO applyJoinCompanyUserDTO) {
        if (applyJoinCompanyUserDTO==null||applyJoinCompanyUserDTO.getMobile()==null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        SysUserDTO sysUserDTO = userService.queryUser(applyJoinCompanyUserDTO.getMobile());
        sysUserDTO.setUsername(applyJoinCompanyUserDTO.getUserName());
        sysUserDTO.setMobile(applyJoinCompanyUserDTO.getMobile());
        sysUserDTO.setEmail(applyJoinCompanyUserDTO.getEmail());
        sysUserDTO.setStatus((short)0);
        sysUserDTO.setUpdateTime(new Date());
        sysUserDTO.setLastLoginCompanyId(applyJoinCompanyUserDTO.getCompanyId());
        SysUser sysUser = BeanHelper.copyProperties(sysUserDTO, SysUser.class);
        userMapper.updateById(sysUser);

        //往企业员工表插入一条数据
        SysCompanyUser sysCompanyUser = new SysCompanyUser();
        sysCompanyUser.setUserId(sysUser.getId());
        sysCompanyUser.setCompanyId(applyJoinCompanyUserDTO.getCompanyId());
        sysCompanyUser.setCompanyName(applyJoinCompanyUserDTO.getCompanyName());
        sysCompanyUser.setEmail(applyJoinCompanyUserDTO.getEmail());
        sysCompanyUser.setTimeEntry(new Date());
        sysCompanyUser.setRemark(applyJoinCompanyUserDTO.getApplyReason());
        sysCompanyUser.setEnable((short)0);
        sysCompanyUser.setCreateTime(new Date());
        sysCompanyUser.setUpdateTime(new Date());
        sysCompanyUser.setPost(applyJoinCompanyUserDTO.getPost());
        sysCompanyUser.setMobile(applyJoinCompanyUserDTO.getMobile());
        sysCompanyUser.setUserName(applyJoinCompanyUserDTO.getUserName());
        sysCompanyUser.setImageUrl(applyJoinCompanyUserDTO.getImageUrl());
        companyUserMapper.insert(sysCompanyUser);

        // 推送消息给管理员，发送消息至MQ，消息微服务接收消息
        // 定义消息内容
        MessageDTO messageDTO = new MessageDTO();
        messageDTO.setMessageType(MessageTypeEnum.COMPANY_APPLY.getType());
        messageDTO.setCompanyId(sysCompanyUser.getCompanyId().toString());
        messageDTO.setTitle(MessageTypeEnum.COMPANY_APPLY.getTitle());
        messageDTO.setContent(sysCompanyUser.getUserName()+"申请加入企业，请及时审批");
        messageDTO.setUseStatus(0);
        messageDTO.setAudience(MessageTypeEnum.COMPANY_APPLY.getAudience());

        //获取当前企业管理员
        SysCompanyUser admin = companyUserMapper.queryMainAdminCompanyUser(sysCompanyUser.getCompanyId());

        messageDTO.setTargets(Lists.newArrayList(admin.getMobile()));
        messageDTO.setApproveStatue(0);
        messageDTO.setApplyUserId(sysCompanyUser.getUserId());
        messageDTO.setApplyUsername(sysCompanyUser.getUserName());
        messageDTO.setApproveUserId(admin.getUserId());
        messageDTO.setApproveUsername(admin.getUserName());

        // 发送消息，参数1-消息的主题:标签，参数2-消息内容（一般用json字符串）
        rocketMQTemplate.convertAndSend("messagePushTopic", JSON.toJSONString(messageDTO));

    }
}
